package thermologic.gui;

import java.util.Date;

import javax.swing.JTable;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.event.ChartProgressEvent;
import org.jfree.chart.event.ChartProgressListener;

import org.jfree.chart.plot.XYPlot;
import org.jfree.data.time.Minute;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.time.TimeSeriesDataItem;

import org.jfree.ui.RectangleInsets;
import thermologic.core.Channel;
import thermologic.core.Sample;

/**
 *
 * @author  Mauricio
 */
public class MainChart extends javax.swing.JPanel {
    
    /** User variables declaration **/
    private TimeSeries timeSeries;
    private JFreeChart chart;
    private ChartPanel chartPanel;
    private JTable samplesTable;
    
    
    /**
     * Creates new form DataloggerChartPanel
     */
    public MainChart() {
        initComponents();
    }
    
    public MainChart(JTable samplesTable)
    {
        this();
        setSamplesTable(samplesTable);
    }
    
    
    private TimeSeries createTimeSeries(Channel channel)
    {
        timeSeries = new TimeSeries(channel.getLabel(), Minute.class);
        
        return timeSeries;
    }
    
    
    private JFreeChart createChart(final Channel channel)
    {   
        String timeLabel = java.util.ResourceBundle.getBundle("properties/language").
                getString("thermologic.labels.dateTime");
        
        /*
         * Create the chart
         * @Fixed string
         */
        chart = ChartFactory.createTimeSeriesChart (
                    channel.getLabel(), timeLabel, channel.toString(),
                    new TimeSeriesCollection(createTimeSeries(channel)),
                    false, true, false
                );           

        /*
         * Configure the Plot
         */
        XYPlot xyplot = chart.getXYPlot();            
        xyplot.setAxisOffset(new RectangleInsets(5D, 5D, 5D, 5D));
        xyplot.setDomainCrosshairVisible(true);
        xyplot.setDomainCrosshairLockedOnData(true);
        xyplot.setRangeCrosshairVisible(true);

        /*
         * Create the LegendItemSource and the 
         * legendTitle object for chart header legends 
         *
        LegendTitle legendTitle = new LegendTitle(new LegendItemSource() {
            public LegendItemCollection getLegendItems() {

                LegendItemCollection itemCollection = new LegendItemCollection();
                
                itemCollection.add(new LegendItem("Inicio: "+ channel.getStartTime(),
                        "","","",new Rectangle(),Color.BLACK));

                itemCollection.add(new LegendItem("Fin: "+ channel.getEndTime(),
                        "","","",new Rectangle(),Color.BLACK));

                itemCollection.add(new LegendItem("Intervalo de muestreo: "+
                        channel.getSampleRate(),"","","",new Rectangle(),Color.BLACK));

                itemCollection.add(new LegendItem("Total muestras: "+
                        channel.getSamplesCount(),"","","",new Rectangle(),Color.BLACK));
                
                return itemCollection;
            }
        });
        legendTitle.setPosition(RectangleEdge.BOTTOM);            
        legendTitle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        legendTitle.setBackgroundPaint(Color.WHITE);
        legendTitle.setBorder(0,0,1,0);
        legendTitle.setPadding(10,10,10,10);
        legendTitle.setLegendItemGraphicPadding(new RectangleInsets(2,15,2,15));
        chart.addLegend(legendTitle);
        */


        /*
         * Create and register the ChartProgressListener
         * interface
         */
        chart.addProgressListener(new ChartProgressListener() {
            
            public void chartProgress(ChartProgressEvent chartProgressEvent)
            {
                XYPlot xyplot = chart.getXYPlot();
                long time = (long)xyplot.getDomainCrosshairValue();
                int index = timeSeries.getIndex(new Minute(new Date(time)));

                if(index >= 0)
                {
                    timeSlider.setValue(index);
                    
                    if(samplesTable != null && samplesTable.getModel().getRowCount() > 0)
                    {   
                        samplesTable.setRowSelectionInterval(index, index);
                        
                        samplesTable.scrollRectToVisible(
                                samplesTable.getCellRect(index,0,false)
                                );
                    }
                }

            }
        });
        
        return chart;
    }
    
    
    private ChartPanel createChartPanel(Channel channel)
    {
        chartPanel = new ChartPanel(createChart(channel));
        
        return chartPanel;
    }
    
    
    private void setUpSlider()
    {
        if(timeSeries != null && timeSeries.getItemCount() > 0)
        {
            timeSlider.setMaximum(timeSeries.getItemCount()-1);
            timeSlider.setMinimum(0);

            timeSlider.addChangeListener(new ChangeListener() {
                public void stateChanged(ChangeEvent changeEvent)
                {
                    TimeSeriesDataItem dataItem = timeSeries.getDataItem(timeSlider.getValue());
                    long time = dataItem.getPeriod().getFirstMillisecond();

                    XYPlot xyplot = chart.getXYPlot();
                    xyplot.setDomainCrosshairValue(time);
                }
            });
        }
    }
    
    
    public void clear()
    {   
        if(timeSeries != null && timeSeries.getItemCount() > 0)
        {
            timeSeries.delete(0, timeSeries.getItemCount()-1);
        }     
    }
    
    
    public void setUp(Channel channel)
    {        
        chartPanel = createChartPanel(channel);               
        timeSeries.setDescription(channel.getLabel());
        
        for (Sample sample: channel.getSamples())
        {   
            timeSeries.addOrUpdate(new Minute(sample.getTimeStamp()), sample.getValue());
        }
        
        //chartPanel.setPreferredSize(new Dimension(width, height));
        scrollPane.setViewportView(chartPanel);
        setUpSlider();
    }

    public void setSamplesTable(JTable samplesTable) {
        this.samplesTable = samplesTable;
    }

    public JTable getSamplesTable() {
        return samplesTable;
    }
    
    
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        lowerPanel = new javax.swing.JPanel();
        timeSlider = new javax.swing.JSlider();
        scrollPane = new javax.swing.JScrollPane();

        setLayout(new java.awt.BorderLayout());

        lowerPanel.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT));
        lowerPanel.add(timeSlider);

        add(lowerPanel, java.awt.BorderLayout.SOUTH);
        add(scrollPane, java.awt.BorderLayout.CENTER);
    }// </editor-fold>//GEN-END:initComponents
    
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel lowerPanel;
    private javax.swing.JScrollPane scrollPane;
    private javax.swing.JSlider timeSlider;
    // End of variables declaration//GEN-END:variables
    
}
